[% setvar title Controllable Data Typing %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>Controllable Data Typing</p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>  Maintainer: Syloke Soong &lt;<a href='mailto:syloke.soong@nsc.com'>syloke.soong@nsc.com</a>&gt;
  Date: 10 Aug 2000
  Last Modified: 12 Aug 2000
  Mailing List: <a href='mailto:perl6-language@perl.org'>perl6-language@perl.org</a>
  Number: 89
  Version: 2
  Status: Developing</pre>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>Provide a choice for a programmer to define non-convertible and
semi-convertible variables with explicit data-types.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<p>Current intelligence and flexibility of Perl variables are extremely
indispensable.  However at times this feature is also extremely
inconvenient. As an example, character string &quot;007&quot; is often mistaken as
int 7. So that concatenation of a variable strings &quot;001999&quot;, &quot;.&quot; , &quot;03&quot;
to form an output filename could, unless with more extensive treatment,
form a filename of 1999.3 instead.  Attempts at storing into a hash with the
key &quot;007&quot; or &quot;  7&quot; rather than 7 is a trying experience. Not to mention
attempts at reading a hash using similar keys.</p>
<p>A compromise between dead-bolted types and liberal types is struck through
constrained and controllable typing. There is a hint of polymorphic behaviour.</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>Retain current flexibility of Perl liberal variables.
Provide a new form of declaring variables:</p>
<pre>	scope cast-type $varname:constraint;</pre>
<p>Valid declarations would be:</p>
<pre>	my $varname;
	my (var-list);
	my cast-type $varname;
	my cast-type (var-list);

	my $varname:constraint;
	my (var-list):constraint;
	my cast-type $varname:constraint;
	my cast-type (var-list):constraint;

	my $varname:(constraint-list);
	my (var-list):(constraint-list);
	my cast-type $varname:(constraint-list);
	my cast-type (var-list):(constraint-list);</pre>
<a name='Simple examples'></a><h2>Simple examples</h2>
<pre>	my $old;
	my int $k;
	my varchar $str;
	my char(5) $zip;
	use CGI; my CGI $q;
	my Net::SNPP ($pg, $pq);

	my int $a = 3.9;
	my int $ceil = 3.9 + 0.5;
	my int $i = 'hello';
	my double $f1 = 'hello';
	my double $f2 = $a;</pre>
<p>$old is the declaration of a liberal type;
$a evaluates to int 3; $ceil evaluates to int 4; $i evaluates to int 0;
$f1 evaluates to double 0.; $f2 evaluates to double 4.;</p>
<a name='Constant constraint'></a><h2>Constant constraint</h2>
<p>A constant confered by the keyword const creates a final value; That value stays
immutably the same throughout the scope of its existence.</p>
<pre>	my $a1:const;
	my int $k1:const;
	my varchar $str1:const;

	my $a21:const = '023';
	my $a22 = 3 + $a21;
	my $a23 = 3.$a21;

	my int $k21:const = '023'; 
	my int $k22:const = 23;
	my varchar $str21:const = 3;
	my char $str22:const = 3;
	my char(1) $str22:const = 3;

	my Net::SNPP ($pg, $pq):const;
	my Net::SNPP ($pr, $ps):const = new Net::SNPP ;
	my Net::SNPP ($pt = $pu, $pv):const = new Net::SNPP ;
	
	use strict(constcroak);
	$str22 = 'hello';</pre>
<p>$a1, $k1, $str1 are henceforth  constantly null liberal, int and varchar respectively;
$$a21 acquires constant value of char(3) '023';
$a22 acquires variable value of liberal-type  26;
$a22 acquires variable value of liberal-type  3023;</p>
<p>$k21, $k22 both acquire constant values of int 23;
$str21, $str22, $str23 all acquire variable values of char(1) 3;</p>
<p>$pg and $pq henceforth vainly reference null objects of Net::SNPP;
Whereas $pr, $ps, $pv usefully and loyally reference separate objects of Net::SNPP;
$pt and $pu both reference the same Net::SNPP object constantly.</p>
<p>The strict directive, default being noconst (disregard any harassment on a const),
is set to croak when an attempt to change the value of constant $str22 is made. Use of</p>
<pre>	use strict(constdie);</pre>
<p>should also be an option.</p>
<a name='Constraint lists'></a><h2>Constraint lists</h2>
<pre>
	my $id:(double,int);

	my int $id1:(double,int) = 1.7;
	my int $id2:(varchar, double) = 2.6;
	my int $id3:(varchar, double, int) = 2.6;
	
	my char $c1 = 'a';
	my char $c2:char = 'a';
	my char $c3:(char) = 'a';

	my $id4:(varchar, double, int) = 2.7;
	my $id5:(varchar, double, int) = 3;
	my $id6:(varchar, double, int) = 'Fatrick Perlland';</pre>
<p>$id is constrained to behave either as double or int;
$id1 is constrained to behave either as double or int, but int casting initialises
it to (double,int) 1;</p>
<p>$id2 and $id3 are similar declarations such that a cast not found in the constraint list
will be spontaneously added to the constraint list; Both acquires (varchar, double)
value of 2.6;</p>
<p>Declarations of $c1, $c2, $c3 are all equivalent forms. Declaration of $c1 follows the
rule of spontaneous appending a cast to its constraint list.</p>
<p>$id4, $id5, $id6 are constrained to behave either as varchar, double or int;
$id4 acquires value of (varchar, double, int) 2.7;
$id5 acquires value of (varchar, double, int) 3;
$id6 acquires value of (varchar, double, int) 'Fatrick Perlland';</p>
<a name='Conditional constraints'></a><h2>Conditional constraints</h2>
<pre>	my $allowedtypes = [int,varchar];
	my $ivd:@$allowedtypes;
	if ($somecondition){push @$allowedtypes , double}</pre>
<p>Initially $ivd would be allowed the behave either as int or varchar.
On condition $somecondition, it is allowed an additional degree of freedom
of double due to appendage to the array referenced by $allowedtypes.</p>
<a name='Suitability and precedence in constraint lists'></a><h2>Suitability and precedence in constraint lists</h2>
<p>The member types chosen as the snap-shot type depends on the rules in order.
First, suitability. Then precedence.</p>
<pre>	my $ie4:(varchar, double, int, char(16)) = 2.7;
	my $ie5:(varchar, double, int, char(16)) = 3;
	my $ie6:(varchar, double, int, char(16)) = 'Fatrick Perlland';</pre>
<p>The declarations has types in the following precedence:
1st varchar, 2nd double, 3rd int, finally char(16).
$ie4 is assigned value 2.7 as double is the most suitable type to receive it.
$ie5 is assigned value 3 as int is most to receive it.
$ie6 has as candidates varchar and char(16), but since varchar is declared in
precedence to char(16), the receiver is a varchar. The inclusion of varchar(16)
is in vain as varchar completely over-rides it.</p>
<a name='Mutable representation of constants'></a><h2>Mutable representation of constants</h2>
<p>While the value of a constant is immutable, its snap-shot representation is not.</p>
<pre>	my $oxygen:(const, char(4), int, double) = '3.3';

	print &quot;#&quot;, $oxygen.&quot;oxymen\n&quot;;
	print &quot;#&quot;, $oxygen + 4 , &quot;oxylady\n&quot;;
	print &quot;#&quot;, $oxygen + 1.5 , &quot;foxylady\n&quot;;	
	print &quot;#&quot;, int ($oxygen + 1.5) , &quot;dixieland\n&quot;;
	print &quot;#&quot;, ($oxygen + 1.5):int , &quot;dixiechicks\n&quot;;
	print &quot;#&quot;, ($oxygen + 1.2378):decimal(3.2) , &quot;Reba\n&quot;;
	</pre>
<p>The following STDOUT results:
# 3.3oxymen
#7oxylady
#4.8foxylady
#4dixieland
#4dixiechicks
#  4.53Reba</p>
<a name='type casting'></a><h2>type casting</h2>
<pre>	my $perl:(int,varchar, double);
	my double $isnotc:(varchar, double) = '4.5'; # $isnot casted to receive double 4.5
	int $perl = $isnotc; # $perl casted to receive int 4
	int $isnotc = $perl; # Do nothing, $isnotc does not have constraint type int

	use strict (croakbadcast);
	int $isnotc = $perl; # Do nothing but a croak will be forthcoming from Perl system

	use strict (diebadcast);
	int $isnotc = $perl; # Do nothing and die

	int $cisnot = $perl; # $cisnot is a new variable and takes on the constraint int</pre>
<a name='What about hash and arrays'></a><h2>What about hash and arrays</h2>
<p>There has been questions - what about hash and arrays?. If they are to be considered
as types then the following is possible.</p>
<pre>	my \@ $aref; #equiv to: my $aref:(\@) = [];
	my \% $hfer; #equiv to: my $href:(\%) = {};
	my int @href; #array of ints
	my CGI @AQ; #array of CGI objects
	my CGI %HQ; #hash which has values resolving to CGI objects	</pre>
<a name='What about pointers to const'></a><h2>What about pointers to const</h2>
<p>In the declaration</p>
<pre>	my int $maine:const = 12;</pre>
<p>$maine loyally references an immutable memory location. Shall there be such where
$mall is a mutable variable allowed to reference only constants? Hmmm...</p>
<pre>	my int $mall:\const = 13;</pre>
<p>There's a hint of wanting Perl references to behave as pointers
and that's not a good attitude. However an array of hash of constants may be declared
and each pigeon hole of the array or hash may reference only constants.</p>
<pre>	my int $shania:const = 11;
	my int @twain:const = ($shania); #valid assignment
	my int $alberta = $twain[0];</pre>
<p>#Perl is not C.</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>Use of colon is plagiarised from email discussions with/from
<a href='mailto:perl6-language@perl.org'>perl6-language@perl.org</a></p>
</div>
